package cc.rengu.igas.bsps.core.service.trans;

import cc.rengu.igas.bsps.common.constant.BspsAppParamConstant;
import cc.rengu.igas.bsps.common.dao.BspsMchntAcctInfoMapper;
import cc.rengu.igas.bsps.common.dao.BspsMchntBaseInfoMapper;
import cc.rengu.igas.bsps.common.dao.BspsMchntBindInfoMapper;
import cc.rengu.igas.bsps.common.dao.BspsUserInfoMapper;
import cc.rengu.igas.bsps.common.dao.impl.BspsMchntAcctInfoMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.BspsMchntBaseInfoMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.BspsMchntBindInfoMapperImpl;
import cc.rengu.igas.bsps.common.dao.impl.BspsUserInfoMapperImpl;
import cc.rengu.igas.bsps.common.entity.MchntAcctInfo;
import cc.rengu.igas.bsps.common.entity.MchntBaseInfo;
import cc.rengu.igas.bsps.common.entity.MchntBindInfo;
import cc.rengu.igas.bsps.common.entity.UserInfo;
import cc.rengu.igas.bsps.common.enums.MchntTypeEnum;
import cc.rengu.igas.bsps.common.enums.RespCodeEnum;
import cc.rengu.igas.bsps.core.model.UserSessionInfo;
import cc.rengu.igas.bsps.core.service.base.ManageService;
import cc.rengu.igas.bsps.facade.base.Header;
import cc.rengu.igas.bsps.facade.request.UserPasswordResetRequest;
import cc.rengu.igas.bsps.facade.response.UserPasswordResetResponse;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.enums.PinTypeEnum;
import cc.rengu.oltp.service.common.enums.SmsTypeEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.PasswordInfo;
import cc.rengu.oltp.service.realize.SafeKeyBoardService;
import cc.rengu.oltp.service.realize.SmsService;
import cc.rengu.oltp.service.realize.impl.SafeKeyBoardServiceImpl;
import cc.rengu.oltp.service.realize.impl.SmsServiceImpl;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.RedisUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

import static com.alibaba.fastjson.JSON.toJSONString;

/**
 * 用户密码重置.
 *
 * @author zhangxuran (联调修改)
 * @version 1.0
 * @date 2020.04.17
 */
public class UserPasswordResetService extends ManageService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        UserPasswordResetRequest userPasswordResetRequest = new UserPasswordResetRequest();
        ConvertUtil.convertOutput(userPasswordResetRequest);
        return userPasswordResetRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        UserPasswordResetRequest userPasswordResetRequest = (UserPasswordResetRequest) request;
        String instId = userPasswordResetRequest.getHeader().getInstId();
        String mchntNo = userPasswordResetRequest.getMchntNo();
        String acctNo = userPasswordResetRequest.getSettleAcctNo();
        String userLoginId = userPasswordResetRequest.getUserId();
        String passwordType = userPasswordResetRequest.getPasswordType();
        String password = userPasswordResetRequest.getNewPassword();
        String confirmPassword = userPasswordResetRequest.getConfirmPassword();
        String chanlId = userPasswordResetRequest.getHeader().getChanlId();
        String smsCode = userPasswordResetRequest.getSmsCode();
        String smsAuthId = userPasswordResetRequest.getSmsAuthId();

        if (StringUtil.isEmptyOrNull(userLoginId) || StringUtil.isEmptyOrNull(smsCode) || StringUtil.isEmptyOrNull(smsAuthId)
                || StringUtil.isEmptyOrNull(passwordType) || StringUtil.isEmptyOrNull(password)) {
            rglog.error("更新密码必填性校验错误");
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }

        /* 密码重置，校验短信验证码 */
        SmsService smsService = new SmsServiceImpl();
        smsService.verifySmsCode(instId, SmsTypeEnum.RESET_PASSWORD.getSmsType(), smsCode, smsAuthId);
        //根据密码类型查询用户及用户绑定商户信息，判断商户信息

        //查询用户信息
        BspsUserInfoMapper bspsUserInfoMapper = new BspsUserInfoMapperImpl();
        UserInfo userInfo;
        if ("00".equals(passwordType)) {
            //登录密码重置
            userInfo = bspsUserInfoMapper.selectBspsUserInfoByUserLoginId(instId, userLoginId);
        } else if ("01".equals(passwordType)) {
            //交易密码重置
            userInfo = bspsUserInfoMapper.selectBspsUserInfoByUserId(instId, userPasswordResetRequest.getUserId());
        } else {
            rglog.error("密码类型错误");
            throw new BizException(RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespCode(), RespCodeEnum.NOT_SUPPORT_ORT_TYPE.getRespDesc());
        }
        if (null == userInfo) {
            rglog.error("用户信息查询失败");
            throw new BizException(RespCodeEnum.USER_EXIST_ERROR.getRespCode(), RespCodeEnum.USER_EXIST_ERROR.getRespDesc());
        }

        BspsMchntBindInfoMapper mchntBindInfoMapper = new BspsMchntBindInfoMapperImpl();
        MchntBindInfo mchntBindInfo = mchntBindInfoMapper.selectBspsMchntBindInfoListByUserIdAndMchntNo(instId, userInfo.getUserId(), mchntNo);
        if (null == mchntBindInfo) {
            rglog.error("用户绑定商户信息查询失败");
            throw new BizException(RespCodeEnum.BIND_MCHNT_STATUS_ERROR.getRespCode(), RespCodeEnum.BIND_MCHNT_STATUS_ERROR.getRespDesc());
        }

        rglog.info("判断是否校验结算账号");
        BspsMchntAcctInfoMapper bspsMchntAcctInfoMapper = new BspsMchntAcctInfoMapperImpl();
        if (MchntTypeEnum.NORMAL_MCHNT.getMchntType().equals(mchntBindInfo.getBindMchntType()) || MchntTypeEnum.CHAIN_MCHNT.getMchntType().equals(mchntBindInfo.getBindMchntType()) ||
                MchntTypeEnum.WECHAT_MCHNT.getMchntType().equals(mchntBindInfo.getBindMchntType()) || MchntTypeEnum.CHAIN_MCHNT_STORE.getMchntType().equals(mchntBindInfo.getBindMchntType())) {
            //校验结算账户
            if (StringUtil.isEmptyOrNull(acctNo)) {
                rglog.error("结算账户信息为空");
                throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
            }
            List<MchntAcctInfo> mchntAcctInfo = null;

            if (MchntTypeEnum.CHAIN_MCHNT_STORE.getMchntType().equals(mchntBindInfo.getBindMchntType())) {
                rglog.info("门店商户判断是否独立维护信息");
                BspsMchntBaseInfoMapper mchntBaseInfoMapper = new BspsMchntBaseInfoMapperImpl();
                MchntBaseInfo mchntBaseInfo = mchntBaseInfoMapper.selectBspsMchntBaseInfoByPrimaryKey(instId, mchntNo);
                if (!"Y".equals(mchntBaseInfo.getIndependentDataFlag())) {
                    rglog.info("门店非独立维护，根据连锁商户号查询结算账户信息");
                    mchntAcctInfo = bspsMchntAcctInfoMapper.selectBspsMchntAcctInfoByMchntNo(instId, mchntBaseInfo.getChainMchntNo());
                } else {
                    rglog.info("门店独立维护，根据商户号查询结算账户信息");
                    mchntAcctInfo = bspsMchntAcctInfoMapper.selectBspsMchntAcctInfoByMchntNo(instId, mchntBaseInfo.getMchntNo());
                }
            } else {
                mchntAcctInfo = bspsMchntAcctInfoMapper.selectBspsMchntAcctInfoByMchntNo(instId, mchntNo);
            }
            if (!CollectionUtils.isEmpty(mchntAcctInfo)) {
                mchntAcctInfo = mchntAcctInfo.stream().filter(item -> item.getSettleAcctNo().equals(acctNo)).collect(Collectors.toList());
            }
            if (CollectionUtils.isEmpty(mchntAcctInfo)) {
                rglog.error("结算账户输入错误，拒绝用户交易重置请求，商户号：<{}>，结算账号：<{}>", mchntNo, acctNo);
                throw new BizException(RespCodeEnum.MCHNT_SETTLE_ACCT_ERROR.getRespCode(), RespCodeEnum.MCHNT_SETTLE_ACCT_ERROR.getRespDesc());
            }
        }

        SafeKeyBoardService safeKeyBoardService = new SafeKeyBoardServiceImpl();
        if (chanlId.equals("PCWEB")) {
            Header header = userPasswordResetRequest.getHeader();
            UserSessionInfo keySessionInfo = JSON.parseObject(RedisUtil.onceGet(header.getSession()), UserSessionInfo.class);
            if (null == keySessionInfo) {
                rglog.error("session超时");
                throw new BizException(RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespCode(), RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespDesc());
            }
            String randomString = keySessionInfo.getRandomString();
            keySessionInfo.setRandomString("");
            RedisUtil.onceSet(header.getSession(), toJSONString(keySessionInfo), BspsAppParamConstant.SESSION_EFFECTIVE_TIME);
            mchntNo = mchntNo.replaceAll("AG", "").replaceAll("PM", "");
            if ("00".equals(passwordType)) {
                PasswordInfo passwordInfo = new PasswordInfo(mchntNo, PinTypeEnum.MIXED, password);
                password = safeKeyBoardService.encryptPassword(instId, null, passwordInfo, null);
            } else {
                PasswordInfo passwordInfo = new PasswordInfo(mchntNo, PinTypeEnum.DIGITAL, password);
                password = safeKeyBoardService.encryptPassword(instId, null, passwordInfo, null);
            }
        } else {
            if ("00".equals(passwordType)) {
                PasswordInfo passwordInfo = new PasswordInfo(mchntNo, PinTypeEnum.MIXED, password);
                password = safeKeyBoardService.encryptPassword(instId, null, passwordInfo, null);
            } else {
                PasswordInfo passwordInfo = new PasswordInfo(mchntNo, PinTypeEnum.DIGITAL, password);
                password = safeKeyBoardService.encryptPassword(instId, null, passwordInfo, null);
            }
        }

        /* 修改用户密码 */
        int iReturnCode = bspsUserInfoMapper.updateBspsPasswordByUserLoginId(instId, userLoginId, password, passwordType);
        if (0 != iReturnCode) {
            rglog.error("用户密码修改失败,iReturnCode:<{}>", iReturnCode);
            throw new BizException(RespCodeEnum.USER_PASSWORD_MODIFY_ERROR.getRespCode(), RespCodeEnum.USER_PASSWORD_MODIFY_ERROR.getRespDesc());
        }

        /* 重组返回结果 */
        BizResponse<UserPasswordResetResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        UserPasswordResetResponse userPasswordResetResponse = new UserPasswordResetResponse();
        userPasswordResetResponse.setRespCode(bizResponse.getRespCode());
        userPasswordResetResponse.setRespDesc(bizResponse.getRespDesc());
        bizResponse.setResult(userPasswordResetResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        UserPasswordResetResponse userPasswordResetResponse = (UserPasswordResetResponse) bizResponse.getResult();
        ConvertUtil.convertInput(userPasswordResetResponse);
    }
}
